#include "hplcqinfinedefine.h"
#include "hplcqinfinecheckpacket.h"
#include "hplcqinfinepfcid.h"
#include "hplcqinfinepacketformat.h"
#include "hplcqinfineprotocolcommondata.h"
#include <QDebug>

namespace hplc
{
namespace qinfine
{

hplc::qinfine::HplcQinfineCheckPacket::HplcQinfineCheckPacket(hplc::qinfine::HplcQinfineProtocolCommonData &data, QObject *parent)
    : QObject (parent)
{
    m_d = &data;

    m_d->m_retryNumber = RETRANSMIT_COUNT;
    m_d->m_tickCheckNumber = 3; // 3次没有收到心跳包，则表示断线
}

HplcQinfineCheckPacket::~HplcQinfineCheckPacket()
{

}

void HplcQinfineCheckPacket::replyCheck(char re)
{
    m_d->m_retryTimerStart = false;
    m_d->m_retryCount = 0;

    switch (re)
    {
    case SYSTEM_COMMUNICATE_ACK:
    {
        // 收到回复，如果发送队列还有数据，则发送
        ack2Send();
    }
        break;
    case SYSTEM_COMMUNICATE_NACK:
    {
        // 帧错误
        qDebug() << "nack";

        emit errorPacket();
        ack2Send();
    }
        break;
    default:
        qDebug() << "error reply" << re;
        break;
    }
}

HplcQinfineSendCommonPacket *HplcQinfineCheckPacket::getSender()
{
    return static_cast<HplcQinfineSendCommonPacket*>(m_d->m_sender);
}

void HplcQinfineCheckPacket::sendRetry()
{
    m_d->m_txBufferHexList << m_d->m_txBufferHex;
    m_d->m_txBufferAsciiList << m_d->m_txBuffer;

    if (m_d->m_txBufferAsciiList.size() == 1)
    {
        m_d->m_retryTimerStart = true;
        m_d->m_retryTimerCount = 0;
        emit m_d->m_sender->requestSend(m_d->m_txBufferAsciiList.first());
    }
}

void HplcQinfineCheckPacket::sendNoRetry()
{
    emit m_d->m_sender->requestSend(m_d->m_txBuffer);
}

void HplcQinfineCheckPacket::ack2Send()
{
    if (m_d->m_txBufferAsciiList.size())
    {
        m_d->m_txBufferAsciiList.removeFirst();
        m_d->m_txBufferHexList.removeFirst();
        if (m_d->m_txBufferAsciiList.size())
        {
            m_d->m_retryTimerStart = true;
            m_d->m_retryTimerCount = 0;
            emit m_d->m_sender->requestSend(m_d->m_txBufferAsciiList.first());
        }
    }
}

void HplcQinfineCheckPacket::resetTickCheck()
{
    m_d->m_tickCheckCount = 0;

    m_d->m_tickCheckTimerStart = true;
    m_d->m_tickCheckTimerCount = 0;
}

void HplcQinfineCheckPacket::onRetryTimeout()
{
    if (m_d->m_txBufferAsciiList.size())
    {
        m_d->m_retryCount++;
        if (m_d->m_retryCount > m_d->m_retryNumber)
        {
            m_d->m_retryCount = 0;

            m_d->m_txBufferAsciiList.removeFirst();
            m_d->m_txBufferHexList.removeFirst();

            emit lostPacket();

//            qDebug() << "retry count overflow";
        }

        if (m_d->m_txBufferAsciiList.size())
        {
            m_d->m_retryTimerStart = true;
            m_d->m_retryTimerCount = 0;
            emit m_d->m_sender->requestSend(m_d->m_txBufferAsciiList.first());
        }
    }
}

void HplcQinfineCheckPacket::onTickCheckTimeout()
{
    m_d->m_tickCheckCount++;
    if (m_d->m_tickCheckCount > m_d->m_tickCheckNumber)
    {
        m_d->m_tickCheckCount = 0;

        emit lostTick();

//        qDebug() << "tick count overflow";
    }
}

void HplcQinfineCheckPacket::onBaseTickTimeout()
{
    if (m_d->m_tickTimerStart)
    {
        m_d->m_tickTimerCount += BASE_TICK_MS;
        if (m_d->m_tickTimerCount >= TICK_TIMEOUT)
        {
            m_d->m_tickTimerCount = 0;

            // 发送心跳包
            getSender()->setTick();
        }
    }

    if (m_d->m_tickCheckTimerStart)
    {
        m_d->m_tickCheckTimerCount += BASE_TICK_MS;
        if (m_d->m_tickCheckTimerCount >= TICK_TIMEOUT)
        {
            m_d->m_tickCheckTimerCount = 0;
            onTickCheckTimeout();
        }
    }

    if (m_d->m_retryTimerStart)
    {
        m_d->m_retryTimerCount += BASE_TICK_MS;
        if (m_d->m_retryTimerCount >= RETRANSMIT_TIMEOUT)
        {
            m_d->m_retryTimerCount = 0;
            onRetryTimeout();
        }
    }
}

} // qinfine
} // hplc
